package com.outfit.job.util;

import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * OkHttpUtil
 *
 * @author ming
 * @date 2019-08-30 16:00
 * <p>company: 杭州行装网络技术有限公司</p>
 * <p>修改履历：</p>
 */
public class OkHttpUtil {
    private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);

    private static OkHttpClient okHttpClient;

    public OkHttpUtil(OkHttpClient okHttpClient) {
        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient();
        }
        OkHttpUtil.okHttpClient = okHttpClient;
    }

    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return 正常请求返回响应内容，无效请求返回 null
     */
    public static String get(String url, Map<String, String> queries) {
        if (StringUtils.isEmpty(url)) {
            return null;
        }
        url = fixUrl(url);
        String queryString = fixQueryString(url, map2String(queries));

        Request request = new Request.Builder()
                .url(url + queryString)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                logger.error("get请求[{}{}]失败,status={}", url, queryString, response.code());
            }
        } catch (Exception e) {
            logger.error("OkHttpUtil get error >> ", e);
        }
        return null;
    }

    /**
     * post
     *
     * @param url    请求的url
     * @param params post form 提交的参数
     * @return 正常请求返回响应内容，无效请求返回 null
     */
    public static String post(String url, Map<String, String> params) {
        if (StringUtils.isEmpty(url)) {
            return null;
        }
        url = fixUrl(url);
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (params != null && params.keySet().size() > 0) {
            for (String key : params.keySet()) {
                builder.add(key, params.get(key));
            }
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                logger.error("post请求[{}]失败,params={},status={}", url, params, response.code());
            }
        } catch (Exception e) {
            logger.error("OkHttpUtil post error >> ", e);
        }
        return null;
    }

    /**
     * getForHeader
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return 正常请求返回响应内容，无效请求返回 null
     */
    public static String getForHeader(String url, Map<String, String> queries) {
        if (StringUtils.isEmpty(url)) {
            return null;
        }
        url = fixUrl(url);
        String queryString = fixQueryString(url, map2String(queries));
        Request request = new Request.Builder()
                .addHeader("key", "value")
                .url(url + queryString)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                logger.error("get请求[{}{}]失败,status={}", url, queryString, response.code());
            }
        } catch (Exception e) {
            logger.error("OkHttpUtil getForHeader error >> ", e);
        }
        return null;
    }

    /**
     * Post请求发送JSON数据
     *
     * @param url        请求地址 http://domain.com
     * @param jsonParams 请求参数 {"name":"admin","pwd":"123456"}
     * @return 正常请求返回响应内容，无效请求返回 null
     */
    public static String postJsonParams(String url, String jsonParams) {
        RequestBody requestBody = RequestBody.create(MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE), jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                logger.error("postJsonParams请求[{}]失败,jsonParams={},status={}", url, jsonParams, response.code());
            }
        } catch (Exception e) {
            logger.error("OkHttpUtil postJsonParams error >> ", e);
        }
        return null;
    }

    /**
     * Post请求发送xml数据
     *
     * @param url       请求地址 http://domain.com
     * @param xmlParams 请求参数
     * @return 正常请求返回响应内容，无效请求返回 null
     */
    public static String postXmlParams(String url, String xmlParams) {
        RequestBody requestBody = RequestBody.create(MediaType.parse(org.springframework.http.MediaType.APPLICATION_XML_VALUE), xmlParams);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            } else {
                logger.error("postXmlParams请求[{}]失败,xmlParams={},status={}", url, xmlParams, response.code());
            }
        } catch (Exception e) {
            logger.error("OkHttpUtil postXmlParams error >> ", e);
        }
        return null;
    }

    private static String fixUrl(String url) {
        if (StringUtils.isEmpty(url)) {
            return url;
        }
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        return url;
    }

    private static String fixQueryString(String url, String queryString) {
        if (StringUtils.isEmpty(url)) {
            logger.warn("fixQueryString warn, url or queryString isEmpty .");
            return "";
        }
        if (!url.contains("?")) {
            queryString = "?" + queryString;
        } else {
            if (!url.endsWith("&")) {
                queryString = "&" + queryString;
            }
        }
        return queryString;
    }


    private static String map2String(Map<String, String> map) {
        if (CollectionUtils.isEmpty(map)) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        map.forEach((k, v) -> {
            stringBuilder.append(k);
            stringBuilder.append("=");
            stringBuilder.append(v);
            stringBuilder.append("&");
        });
        return stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
    }
}
